package nl.Viewer.ViewManager.Views.ParameterView;

import java.util.ArrayList;

import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

import nl.Viewer.SerializedObjects.Parameter;
import nl.Viewer.Sessions.Communication.JavaPythonUtil;
import nl.Viewer.Sessions.Communication.ParameterException;
import nl.Viewer.ViewManager.Controllers.GenericController;

/**
 * A default table model for a parameter table in the parameter view. The first column is the parameter name, the second
 * is the value (which is filled with its python representation, and which may be edited in-table)
 * 
 * @author Jeroen Verschuur
 * 
 */

public class DefaultParameterTableModel extends AbstractTableModel {
   private static final long      serialVersionUID = -9062469634357968219L;
   protected ArrayList<Parameter> parameters;
   private boolean                renderNeeded     = false;
   private GenericController      controller;

   /**
    * The constructor of the parameter model. Additional logic is added to parse a list of strings for labels, and a
    * list of booleans for the visibilities of aligned representations
    * 
    * @param editableParameters
    * @param labels
    * @param visibilities
    */
   public DefaultParameterTableModel( GenericController controller, ArrayList<Parameter> editableParameters ) {
      this.controller = controller;
      this.parameters = editableParameters;
   }

   public String getColumnName( int columnIndex ) {
      switch (columnIndex) {
         case 0:
            return "Parameter";
         default:
            return "Value";
      }
   }

   public int getColumnCount() {
      return 2;
   }

   public int getRowCount() {
      return parameters.size();
   }

   public Object getValueAt( int rowIndex, int columnIndex ) {
      Parameter p = parameters.get( rowIndex );
      if( p == null )
         return "";

      if( columnIndex == 0 ) {
         return p.getParameterName();
      } else {
         return p.getPythonRepresentation();
      }
   }

   public boolean isCellEditable( int row, int col ) {
      if( col == 0 )
         return false;

      // actually, there will not be any non-editable parameters in the list, so the code below is just to be safe
      Parameter p = parameters.get( row );
      if( p == null )
         return false;

      return p.isUserModifiable();
   }

   public void setValueAt( Object value, int row, int col ) {
      if( col == 0 )
         return;

      if( value.equals( getValueAt( row, col ) ) )
         return;

      Parameter p = parameters.get( row );
      if( p == null )
         return;

      // parse value (python syntax) and check whether this input is correct
      try {
         Object javaObject = JavaPythonUtil.parsePythonObjectToJavaObject( value.toString() );
         p.setParameterValue( JavaPythonUtil.convertJavaObjectToParameter( javaObject, p.getParameterType(),
               p.getParameterLength() ) );
         p.setModified( true );
         setRenderNeeded( true );
         fireTableCellUpdated( row, col ); // setRenderNeeded(true) requires a new call
         controller.requestNewRender();
      }
      catch( ParameterException pe ) {
         JOptionPane.showMessageDialog( null, "Deze waarde is niet toegestaan: " + pe );
      }

   }

   public boolean isRenderNeeded() {
      return renderNeeded;
   }

   public void setRenderNeeded( boolean renderNeeded ) {
      this.renderNeeded = renderNeeded;
   }

}
